ERC884(Delaware General Corporations Law (DGCL) compatible share token)
前提
アメリカの法人は基本的にデラウェア州に登記される
そもそも、法人税を払わなくていいというとこから始まった
-> その後、様々な訴訟を経て、企業経営にとって洗練された法制度、裁判ノウハウ、判例などが溜まっている(流石に法人税はどこに事業実態があるかで課税される模様)
+ 登記コストも僅かだが安い
デラウェア州ではブロックチェーンでの登記(tokenを会社のシェアとして認める)法案が通っている!
詳細(READMEより)
シンプルサマリー
アブスト
デラウェア州ではすでに、法が改正され、ブロックチェーン上での会社のシェア(=equity)が権利として認められている。(ブロックチェーン上にtokenを株式として登記できる!)。つまりtradableなERC20ベースでの株式tokenが作れる。それは以下の要件が必要
1. tokenのオーナーのIDが承認されてること(KYC済みであること)
2. Section 224 of The Act にしたがった Corporations Stock ledger として実装されているコントラクトであること。それは3つのポイントが有り、(i) Sections 219 and 220 of The Act 企業の情報開示, (ii) Sections 156, 159, 217(a) and 218 of The Act にしたがった特殊な情報(party paid share, total amount paid, total amount to be paid)の記録 (iii) section 159 of The Act に従った権利の移転(transfer)。これは Article 8 of subtitle I of Title 6 に従う。
3. 各々のトークンはsingleなshareに対応していないといけない。
4. 秘密鍵をなくした(ないしは何らかの理由でtokenへのアクセスを失った)シェアホルダーが、古いアドレスをキャンセルし、新しいアドレスを再発行して、再びトークンを取り戻せる
動機
デラウェア州ではtokenでの株式シェアの標章が法律で保証されているので、それにのっとったtokenはIPOマーケットにも上場可能。一方、いまだtokenのstandardがない。ERC-20はKYC/AMLのチェックも標準実装されてないので、実装しようと考えた。ERC721に関しては、実装自体は可能だが、法律が追いついていないためfuture workとしている
仕様
erc20ベースにいくつか拡張
event
event VerifiedAddressAdded(address indexed addr, bytes32 hash, address indexed sender) : 新しく承認されたaddressがcontractに追加されたとき発火
event VerifiedAddressRemoved(address indexed addr, address indexed sender): 承認されていたaddressがcontractから取り除かれたときに発火
event VerifiedAddressUpdated(address indexed addr, bytes32 oldHash, bytes32 hash, address indexed sender): 承認されていたaddressがupdateされたときに発火
event VerifiedAddressSuperseded(address indexed original, address indexed replacement, address indexed sender): 古いaddressをキャンセルし、新しいaddressに置き換えたときに発火。秘密鍵をなくしたときなどに利用される
function
function addVerified(address addr, bytes32 hash) public: 新しく承認するaddressを追加
function removeVerified(address addr) public: 承認されていたaddressを削除
function updateVerified(address addr, bytes32 hash) public: 承認されていたaddressをupdate
function cancelAndReissue(address original, address replacement) public: 秘密鍵をなくしたときに、古いaddressをcancelして、新しいaddressを発行し、そこにtokenも移動
function transfer(address to, uint256 value) public returns (bool): transferのオーバーライド。受け取る側も、msg.senderも承認されたaddressでないといけない。
function transferFrom(address from, address to, uint256 value) public returns (bool): transferFromのオーバーライド。transferと同じ制限
function isVerified(address addr) public view returns (bool): addressがすでに承認されているかを確認する関数
function isHolder(address addr) public view returns (bool): addressがシェアホルダーかどうかをチェックする関数
function hasHash(address addr, bytes32 hash) public view returns (bool): 与えられたハッシュがaddressに紐付いているかをチェックする関数
function holderCount() public view returns (uint): tokenホルダーの数を返す関数
function holderAt(uint256 index) public view returns (address): tokenhodlerのリストのindexに合致した人のaddressを返す関数
function isSuperseded(address addr) public view returns (bool): addressがすでに置き換えられたものかどうかチェックする関数
function getCurrentFor(address addr) public view returns (address): 置き換えられたaddressはチェーンになっているため、最新の(有効な)addressを取得する関数
SECのrequirement
crowdsale時にUSDのrateが必要 -> USD/ETHのoracle経由で
crowdsaleの内容によっては投資家の数の制限が必要 -> holderCountとisHolderで
などなど
IDにhash valueを使う
The Act に乗っ取ると、issuerは投資家の情報(名前、住所etc)を把握してないといけない。一方public chainにこれらのdataをのせるのは致命的なプライバシーの問題になるため推奨しない。off-chainのdatabaseで(名前, 住所, ethのアドレス)を管理する。これらをくっつけ、hash値をとったものをpublic chainにのこしておき、hasHashで一致しているかを確認する。
userが秘密鍵をなくしたときの対処
cancelAndReissue関数で対応
権限の管理
addVerified, removeVerified, updateVerified を各自実装することで対応。
サンプル実装